﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Medianamik.Core.Synchronization
{
    public abstract class GenericNodeToRecordConverter<TRecord, TRecordProperty>
    {
        public IEnumerable<Record> ConvertToRecords(IEnumerable<TRecord> genericRecords)
        {
            var records = new List<Record>();

            foreach (var genericRecord in genericRecords)
            {
                var record = ConvertToRecord(genericRecord);

                if (record != null)
                {
                    records.Add(record);
                }
            }

            return Exceptions.Count() > 0 ? new List<Record>() : records;
        }

        public Record ConvertToRecord(TRecord genericRecord)
        {
            var record = GetRecord(genericRecord);

            if (record != null)
            {
                foreach (var property in GetProperties(genericRecord)
                    .Select(genericProperty => GetRecordProperty(genericProperty))
                        .Where(property => property != null))
                {
                    record.Properties.Add(property);
                }
            }

            return record;
        }

        public IList<RecordProperty> GetRecordProperties(TRecord genericRecord)
        {
            var recordProperties = new List<RecordProperty>();

            foreach (var property in GetProperties(genericRecord)
                    .Select(genericProperty => GetRecordProperty(genericProperty))
                        .Where(property => property != null))
            {
                recordProperties.Add(property);
            }

            return recordProperties;
        }

        public abstract Record GetRecord(TRecord node);
        public abstract IEnumerable<TRecordProperty> GetProperties(TRecord instance);
        public abstract RecordProperty GetRecordProperty(TRecordProperty property);

        protected void AddException(string message)
        {
            _exceptions.Add(new Exception(message));
        }
        public IEnumerable<Exception> Exceptions
        {
            get { return _exceptions; }
        }

        readonly List<Exception> _exceptions = new List<Exception>();
    }
}
